/* **************************************************
 * Archivo: TDAServidorInseguro.c                   *
 * Fecha: 01/03/2010                                *
 * Autor: Ariel Liguori / Maximiliano Rodriguez
 * Redise�o: Nahuel Persia
 *                                                  *
 * **************************************************/

#include "TDAServerLog.h"
#include "TDAServidorInseguro.h"
#include "TDAClienteCorreo.h"
#include <stdlib.h>
#include "TDACola.h"
#include "TDACorreo.h"
#include "logdebug.h"
#include <string.h>
#include <time.h>
#include "TDA_DNS.h"


void extraerDominio(char* dirMail,char* dominio){

    int i=0,j=0;
    int enc=FALSE;


    for( ; i<=MAX_ADDR_SIZE ; i++){
        if (dirMail[i]=='@')
            enc=TRUE;

        if (enc){
            dominio[j]=dirMail[i+1];
            j++;
        }
    }
}



void crearServidor(TDAServidorInseguro* servidor,char* dominio,TDA_DNS *DNS) {
    servidor->cantidadCorreos = 0;
    servidor->qtyEventos = 0;
    P_Crear( &(servidor->pilaLog) ,sizeof(TDAServerLog));
    strcpy(servidor->dominio,dominio);
    servidor->DNS=DNS;

}


int getCantidadCorreos(TDAServidorInseguro servidor) {
    return servidor.cantidadCorreos;
}

void destruirServidor(TDAServidorInseguro* servidor) {

}

int agregarCorreo(TDAServidorInseguro* servidor, TDACorreo correo) {

    /* Defino variables auxiliares para los campos del correo, si bien *
     * puedo acceder directamente con "correo.<attr>" es recomendable  *
     * no tener interaccion directa con el correo y valerse de los     *
     * getterS correspondientes.
     */

    char remitente[MAX_ADDR_SIZE] = {0};
    char dest[MAX_ADDR_SIZE] = {0};
    char asunto[MAX_SUBJECT_SIZE] = {0};
    char cuerpo[MAX_BODY_SIZE] = {0};
    char filename[MAX_FILENAME] = {0};
    char auxDest[MAX_QTY_DEST][MAX_ADDR_SIZE] = {{0}};
    char auxDominios[MAX_QTY_DOMINIOS][MAX_DOMINIO_SIZE] = {{0}};
    time_t fechaHora;
    int i=0, j=0, k=0, flag=0, index=0, token=0, qtyDominios = 1;

    char dominio[MAX_DOMINIO]={0};
    TDAServidorInseguro* servidorDistinto = NULL;


    TDACorreo *aux,*aux2;

    aux = &( servidor->correo[servidor->cantidadCorreos] );

    getAsunto(correo, asunto);
    getTextoCuerpo(correo, cuerpo);
    getRemitente(correo, remitente);
    getFilename(correo, filename);

    time(&fechaHora);

    for ( i = 0, index=1; i < getCantidadDestinatarios(correo) ; i++){

        token = 0;
        getDestinatarioX(&correo, dest, i);
        strcpy(auxDest[i],dest);

        extraerDominio(dest,dominio);


        /* Chequeo si un mail viene a este server. */
        if (strcmp(dominio,servidor->dominio)==0)
            flag = 1;
    }

    if ( flag ){
        setTextoCuerpo( aux, cuerpo);
        setAsunto(aux, asunto);
        setRemitente(aux, remitente);
        setFilename(aux, filename);
        setFechaHoraEnviado(aux, fechaHora);

        for ( i = 0 , j = 0 ; i < getCantidadDestinatarios(correo) ; i++){
            getDestinatarioX(&correo, dest, i);
            strcpy(aux->destinatarios[i],dest);

            extraerDominio(dest,dominio);

            if (strcmp(dominio,servidor->dominio)==0){
                strcpy(servidor->destOrig[servidor->cantidadCorreos][j],dest);
                j++;
            }
        }

        addDataToLog(servidor, fechaHora, asunto, remitente, RCVD_MAIL);
        aux->qtyDest = getCantidadDestinatarios(correo);

        servidor->cantidadCorreos++;

    }


    for ( i=0 , index=1; (i < getCantidadDestinatarios(correo)) && !flag ; i++){

        getDestinatarioX(&correo, dest, i);
        token=0;
        extraerDominio(dest,dominio);

        for( k=1; k<=qtyDominios; k++)
            if ( !strcmp(auxDominios[k],dominio) ){
                token = 1;
            }

        if ( !token ){
            strcpy(auxDominios[index],dominio);
            index++;
            qtyDominios++;
        }

        if (    ( strcmp(dominio,servidor->dominio) != 0) && !token ){

            /* Mail dirigido a otro servidor */


            servidorDistinto = queryDNS((servidor->DNS),dominio,servidorDistinto);


            if ( (int)servidorDistinto == 1 )
                return EXIT_FAILURE;

            aux2 = &( servidorDistinto->correo[servidorDistinto->cantidadCorreos] );

            setTextoCuerpo( aux2, cuerpo);
            setAsunto(aux2, asunto);
            setRemitente(aux2, remitente);
            setFilename(aux2, filename);
            setFechaHoraEnviado(aux2, fechaHora);

            aux2->qtyDest = getCantidadDestinatarios(correo);

            for ( j=0 , k=0 ; j < getCantidadDestinatarios(correo) ; j++){
                getDestinatarioX(&correo, dest, j);
                strcpy(aux2->destinatarios[j],dest);

                if (strcmp(dominio,servidorDistinto->dominio)==0){
                    strcpy(servidorDistinto->destOrig[servidorDistinto->cantidadCorreos][k],dest);
                    k++;
                }
            }

            addDataToLog(servidorDistinto, fechaHora, asunto, remitente, RCVD_MAIL);
            servidorDistinto->cantidadCorreos++;

        }

    }

    return 0;

}

int obtenerProximoCorreo(TDAServidorInseguro* servidor, char* destinatario, TDACorreo* correo) {

    int i=0,j=0;
    TDACorreo *aux;
    char dest[MAX_ADDR_SIZE]={0};/*MAX SIZE DEST*/

    while(i < servidor->cantidadCorreos ){

        aux = &(servidor->correo[i]);

        printf("\n Buscando mails para : %s",destinatario);
        if ( ( buscarDestinatario( &(servidor->correo[i]), destinatario)) != DEST_NOT_FOUND ){

            setRemitente(correo, aux->remitente);
            setAsunto(correo, aux->asunto);

            setFilename(correo, aux->filename);
            setTextoCuerpo(correo, aux->cuerpo);
            setFechaHoraEnviado(correo, aux->fechaHora);

            addDataToLog(servidor, aux->fechaHora, aux->asunto, destinatario, SENDED_MAIL);

            correo->qtyDest = getCantidadDestinatarios(*aux);

            for ( ; j < getCantidadDestinatarios(*aux) ; j++){

                strcpy(dest,servidor->destOrig[i][j]);
                strcpy(correo->destinatarios[j],dest);
            }

            eliminarDestinatario( aux, destinatario);
            return EXIT_SUCCESS;

        }

        i++;
    }

	return EXIT_FAILURE;
}


int obtenerCorreos(TDAServidorInseguro *servidor, char *dest, TCola *correos){

    int i=0, j=0;
    int flag=0;
    TDACorreo *aux = NULL;
    TDACorreo copia;
    char remitente[MAX_ADDR_SIZE]={0};
    char asunto[MAX_SUBJECT_SIZE]={0};
    char cuerpo[MAX_BODY_SIZE]={0};
    char filename[MAX_FILENAME]={0};
    time_t fechaHora;

    while(i < servidor->cantidadCorreos ){

        aux = &(servidor->correo[i]);

        if ( ( buscarDestinatario( aux, dest)) != DEST_NOT_FOUND ){

            getAsunto(*aux, asunto);
            getTextoCuerpo(*aux, cuerpo);
            getRemitente(*aux, remitente);
            getFilename(*aux, filename);
            fechaHora = getFechaHoraEnviado(*aux);

            setTextoCuerpo( &copia, cuerpo);
            setAsunto(&copia, asunto);
            setRemitente(&copia, remitente);
            setFilename(&copia, filename);
            setFechaHoraEnviado(&copia, fechaHora);

            copia.qtyDest = aux->qtyDest;

            addDataToLog(servidor, fechaHora, asunto, dest, SENDED_MAIL);

            for( j = 0; j < aux->qtyDest ; j++)
                strcpy(copia.destinatarios[j],servidor->destOrig[i][j]);

            C_Agregar(correos, &copia );

            eliminarDestinatario( aux, dest);

            if ( !getCantidadDestinatarios(*aux) )
                destruirCorreo(aux);

            flag++;
        }

        i++;

    }

    return flag;
}

void addDataToLog(TDAServidorInseguro* servidor, time_t fechaHora, char* asunto, char* remitente, int tipoData){

    TDAServerLog logData;

    logData.fechaHora = fechaHora;
    strcpy(logData.asunto,asunto);
    strcpy(logData.remitente,remitente);
    logData.tipoData = tipoData;

    P_Agregar( &(servidor->pilaLog), &logData);

    servidor->qtyEventos +=1;

}


int escribirLog(TDAServidorInseguro servidor, FILE* archivo){

    int i=0;
    TDAServerLog logData;
    struct tm *date;

    for ( i=0 ; i < servidor.qtyEventos ; i++){

        P_Sacar( &(servidor.pilaLog), &logData);

        date = localtime ( &(logData.fechaHora) );

        /* Elimino el caracter de nueva linea (en caso de existir) del asunto. */
        logData.asunto[strcspn ( logData.asunto, "\n" )] = '\0';

        if ( logData.tipoData == SENDED_MAIL ){
            fprintf(archivo,"<%d-%d-%d> <%02d:%02d:%02d> : <%s> recibio el mensaje \"<%s>\"\n",
                            (date->tm_year+1900),(date->tm_mon+1),date->tm_mday,date->tm_hour,
                            date->tm_min,date->tm_sec,logData.remitente, logData.asunto);
        }else
            fprintf(archivo,"<%d-%d-%d> <%02d:%02d:%02d> : <%s> envio el mensaje \"<%s>\"\n",
                            (date->tm_year+1900),(date->tm_mon+1),date->tm_mday,date->tm_hour,
                            date->tm_min,date->tm_sec,logData.remitente, logData.asunto);
    }

    P_Vaciar(&servidor.pilaLog);

    return EXIT_SUCCESS;
}








